﻿//----------------------------------------------------------------
// Desc: 断言功能
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2010-06-11
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//   FMD5_OBJECT& md5;
// 多块MD5计算
//   FMD5_CONTEXT context;
//   FMD5_Start(&context);
//   FMD5_Update(&context, buffer1, bufferlen1);
//   FMD5_Update(&context, buffer2, bufferlen2);
//   FMD5_Finish(&context, md5);
// 或者单块计算
//   FMD5_Make(buffer, bufferlen, md5);
//----------------------------------------------------------------
#pragma once


struct FMD5_CONTEXT
{
    UINT32 total[2];
    UINT32 state[4];
    BYTE buffer[64];
};


#pragma pack(push, 1)

struct FMD5_OBJECT
{
    FDECLARE_STRUCT(FMD5_OBJECT);

    BYTE digest[eCD_MD5_MAX];

    FMD5_OBJECT()
    {
        empty();
    }
    FINLINE void empty()
    {
        FMemzero(digest, sizeof(digest));
    }
    FINLINE bool is_empty()
    {
        for (size_t i = 0; i < eCD_MD5_MAX; ++i)
        {
            if (digest[i])
                return false;
        }
        return true;
    }
    FINLINE bool operator == (const FMD5_OBJECT& rr)
    {
        return FMemcmp(digest, rr.digest, sizeof(digest)) == 0;
    }
};

#pragma pack(pop)


extern FAPI void FMD5_Start(FMD5_CONTEXT* ctx);
extern FAPI void FMD5_Process(FMD5_CONTEXT* ctx, BYTE data[64]);
extern FAPI void FMD5_Update(FMD5_CONTEXT* ctx, BYTE* input, UINT32 length);
extern FAPI void FMD5_Finish(FMD5_CONTEXT* ctx, FMD5_OBJECT& md5);

// MD5转为字符串
extern FAPI void FMD5_ToStringW(FMD5_OBJECT& md5, FStringW& out);
extern FAPI void FMD5_ToStringA(FMD5_OBJECT& md5, FStringA& out);
// 单数据块快速生成MD5
extern FAPI void FMD5_Make(BYTE* buffer, int bufferlen, FMD5_OBJECT& md5);
// MD52个字符转为十进制
extern FAPI BYTE FMD5_CharToHex(const ACHAR* md5src);
// 通过MD5串转为MD5值
extern FAPI bool FMD5_FromMD5String(const ACHAR* md5src, FMD5_OBJECT& md5);


#ifdef UNICODE
#define FMD5_ToString       FMD5_ToStringW
#else
#define FMD5_ToString       FMD5_ToStringA
#endif